// Package controllers
// @program: BannerStudioBlog.background
// @author: Hyy
// @create: 2021-10-27 21:48
package controllers

import (
	"bannerstudioblog/models"
	"bannerstudioblog/utils"
	"encoding/json"
	"errors"
	"github.com/astaxie/beego/logs"
	"io/ioutil"
	"log"
	"net/http"
	"net/url"
	"strconv"
	"time"
)

// UserController
// user API
type UserController struct {
	baseController
}

// 解析请求，并将请求体存储到v中
// unmarshalPayload
// @Param	v	interface{}	true	"接收解析后的请求体的变量"
func (u *UserController) unmarshalPayload(v interface{}) error {
	// json 解析
	// Unmarshal(data []byte, v interface{})
	// 将json字符串解码到相应的数据结构
	err := json.Unmarshal(u.Ctx.Input.RequestBody, &v)
	if err != nil {
		logs.Error("RequestBody 解析失败！")
		logs.Error("unmarshal payload of %s error: %s", u.Ctx.Request.URL.Path, err)
	}
	return nil
}

// Respond
// @Title Respond
// @Description 返回前端的信息
// @Param	code		 	int				true		"状态码"
// @Param	message		 	string			true		"返回信息"
// @Param	data		 	...interface{}	true		"数据"
func (u *UserController) Respond(code int, message string, data ...interface{}) {
	//c.Ctx.Output.SetStatus(code)
	var d interface{}
	if len(data) > 0 {
		d = data[0]
	}
	u.Data["json"] = struct {
		Code    int         `json:"code"`
		Message string      `json:"message"`
		Data    interface{} `json:"data,omitempty"`
	}{
		Code:    code,
		Message: message,
		Data:    d,
	}
	u.ServeJSON()
}

// Login
// @Title Login
// @Description 跳转到授权中心
// @router /login [get]
func (u *UserController) Login() {
	u.Redirect("https://oauth.bannerstudio.club/oauth/authorize?client_id=bannerstudioblog02&response_type=code&scope=all&redirect_uri=http://localhost:8081/api/user/login/callback", http.StatusTemporaryRedirect)
}

// GetToken
// @Title GetToken
// @Description 从授权中心获取token
// @Success 200 {string}
// @Failure 403 body is empty
// @router /login/callback [get]
func (u *UserController) GetToken() {
	code := u.GetString("code")
	tokenUrl := "https://oauth.bannerstudio.club/oauth/token"

	logs.Info(tokenUrl)
	data := url.Values{
		"code":          {code},
		"client_id":     {"bannerstudioblog02"},
		"client_secret": {"bannerstudioblog"},
		"redirect_uri":  {"http://localhost:8081/api/user/login/callback"},
		"grant_type":    {"authorization_code"},
	}
	resp, err := http.PostForm(tokenUrl, data)
	if err != nil {
		log.Println(err)
		u.Respond(http.StatusBadRequest, "获取失败", err)
		return
	}
	defer resp.Body.Close()
	bodyContent, err := ioutil.ReadAll(resp.Body)
	respMap := make(map[string]interface{})
	err = json.Unmarshal(bodyContent, &respMap)
	if err != nil {
		log.Println(err)
		u.Respond(http.StatusBadRequest, "获取失败")
		return
	}
	u.Respond(http.StatusOK, "获取成功", respMap["access_token"].(string))
	return
}

// ParseToken
// @Title ParseToken
// @Description 解析token 获取authUser
// @Success 200 {string}
// @Failure 403 body is empty
// @router /getAuth [get]
func (u *UserController) ParseToken() {
	token := u.Ctx.Input.Header("token")
	tokenMap, err := utils.ValidateToken(token)
	if err != nil {
		logs.Error(err.Error())
		u.Data["json"] = models.GetRevaErr(err, "解析失败")
		return
	}
	var user models.User
	user.Username = tokenMap["user_name"].(string)
	err = u.o.Read(&user, "username")
	if err != nil {
		log.Println(err)
		u.Respond(http.StatusBadRequest, "从数据库中获取用户信息失败", user)
		return
	}
	var v models.Visitor
	err = u.o.QueryTable(v.TableName()).Filter("user_id", user.Id).Filter("is_author", 1).One(&v)
	if err != nil {
		log.Println(err)
		log.Println("从数据库中获取用户个人的访客信息失败")
		v.User = &models.User{Id: user.Id}
		v.IsAuthor = 1
		v.VTime = time.Now()
		v.VName = user.Nickname
		v.VHeadPortrait = user.HeadPortrait
		v.VEmail = "------"
		v.VHomePage = "******"
		_, err = u.o.Insert(&v)
		if err != nil {
			err = errors.New("添加作者访客信息失败")
			u.Data["json"] = models.GetRevaOk(user)
			u.ServeJSON()
			return
		}
	}
	u.Data["json"] = models.GetRevaOk(struct {
		models.User
		int
	}{
		user,
		v.Id,
	})
	u.ServeJSON()
}

// GetUserinfoById
// @Title	GetUserinfoById
// @Description Query a blog
// @Param	id 	path	int true	"根据用户id获取用户信息"
// @Success 201 获取用户信息成功
// @Failure 403 获取用户信息失败
// @router /GetUserinfoById/:id [get]
func (u *UserController) GetUserinfoById() {
	Id, err := u.GetInt(":id")
	if err != nil {
		u.Data["json"] = models.GetRevaErr(err, "后台获取数据失败")
		u.ServeJSON()
		return
	}
	var userinfo = models.User{Id: Id}
	err = u.o.Read(&userinfo)
	if err != nil {
		u.Data["json"] = models.GetRevaErr(err, "后台操作数据库失败")
		u.ServeJSON()
		return
	}
	//// 给用户信息追加博客信息
	//var blog models.Blog
	//var blogs []models.Blog
	//all, err := b.o.QueryTable(blog.TableName()).Filter("uid_id", userinfo.Id).All(&blogs)
	//if err != nil {
	//	b.Data["json"] = models.GetRevaErr(err, "从数据库查询博客信息失败")
	//	b.ServeJSON()
	//	return
	//}
	//for i := 0; i < int(all); i++ {
	//	userinfo.Blog = append(userinfo.Blog, &blogs[i])
	//}
	//// 给用户信息追加标签和分类信息
	//var types models.Type
	//var allType []models.Type
	//allTypes, err := b.o.QueryTable(types.TableName()).Filter("uid_id", userinfo.Id).All(&allType)
	//if err != nil {
	//	b.Data["json"] = models.GetRevaErr(err, "从数据库中查询博客分类失败")
	//	b.ServeJSON()
	//	return
	//}
	//for i := 0; i < int(allTypes); i++ {
	//	userinfo.Types = append(userinfo.Types, &allType[i])
	//}
	//var labels models.Label
	//var allLabel []models.Label
	//allLabels, err := b.o.QueryTable(labels.TableName()).Filter("uid_id", userinfo.Id).All(&allLabel)
	//if err != nil {
	//	b.Data["json"] = models.GetRevaErr(err, "从数据库中查询博客标签失败")
	//	b.ServeJSON()
	//	return
	//}
	//for i := 0; i < int(allLabels); i++ {
	//	userinfo.Labels = append(userinfo.Labels, &allLabel[i])
	//}
	// 初始化用户信息
	if len(userinfo.HeadPortrait) == 0 {
		userinfo.HeadPortrait = "默认头像的地址"
	}
	if len(userinfo.Theme) == 0 {
		userinfo.Theme = "默认主题"
	}
	u.Data["json"] = models.GetRevaOk(userinfo)
	u.ServeJSON()
}

// GetUserinfoByDomainNameSuffix
// @Title	GetUserinfoByDomainNameSuffix
// @Description 根据域名后缀获取用户信息
// @Param	DomainNameSuffix 	path	string true	"域名后缀"
// @Success 201 获取用户信息成功
// @Failure 403 获取用户信息失败
// @router /GetUserinfoByDomainNameSuffix/:DomainNameSuffix [get]
func (u *UserController) GetUserinfoByDomainNameSuffix() {
	DomainNameSuffix := u.GetString(":DomainNameSuffix")
	var userinfo = models.User{DomainNameSuffix: DomainNameSuffix}
	err := u.o.Read(&userinfo, "DomainNameSuffix")
	if err != nil {
		u.Data["json"] = models.GetRevaErr(err, "后台操作数据库失败")
		u.ServeJSON()
		return
	}
	// 初始化用户信息
	if len(userinfo.HeadPortrait) == 0 {
		userinfo.HeadPortrait = "默认头像的地址"
	}
	if len(userinfo.Theme) == 0 {
		userinfo.Theme = "默认主题"
	}
	if len(userinfo.DomainNameSuffix) == 0 {
		userinfo.DomainNameSuffix = strconv.Itoa(userinfo.Id)
	}
	userinfo.Username = ""
	userinfo.Password = ""
	u.Data["json"] = models.GetRevaOk(userinfo)
	u.ServeJSON()
}

// AddUserinfo
// @Title AddUserinfo
// @Description 添加用户信息
// @Param body	body	models.User true	"添加用户信息，其中uid和昵称必填"
// @Success 201 添加成功
// @Failure 403 添加失败
// @router /AddUserinfo/ [post]
func (u *UserController) AddUserinfo() {
	var userinfo models.User
	err2 := json.Unmarshal(u.Ctx.Input.RequestBody, &userinfo)
	if err2 != nil {
		u.Data["json"] = models.GetRevaErr(err2, "获取json结构体失败")
		u.ServeJSON()
		return
	}
	if len(userinfo.DomainNameSuffix) == 0 {
		userinfo.DomainNameSuffix = strconv.Itoa(userinfo.Id)
	}
	_, err := u.o.Insert(&userinfo)
	if err != nil {
		u.Data["json"] = models.GetRevaErr(err, "后台操作数据库失败")
		u.ServeJSON()
		return
	}
	u.Data["json"] = models.GetRevaOk(userinfo)
	u.ServeJSON()
}

// DeleteUserinfoById
// @Title DeleteUserinfoById
// @Description	删除用户信息
// @Param id path	int	true "根据id删除用户信息"
// @Success 201	删除成功
// @Failure 403 删除失败
// @router /DeleteUserinfoById/:id [delete]
func (u *UserController) DeleteUserinfoById() {
	Id, err := u.GetInt(":id")
	if err != nil {
		u.Data["json"] = models.GetRevaErr(err, "后台获取数据失败")
		u.ServeJSON()
		return
	}
	i, err := u.o.Delete(&models.User{Id: Id})
	if err != nil {
		u.Data["json"] = models.GetRevaErr(err, "后台操作数据库失败")
		u.ServeJSON()
		return
	}
	u.Data["json"] = models.GetRevaOk("成功删除" + strconv.Itoa(int(i)) + "条数据")
	u.ServeJSON()
}

// UpdateUserinfo
// @Title UpdateUserinfo
// @Description 修改用户信息
// @Param body body		models.User	true "修改用户信息"
// @Success 201	修改成功
// @Failure 403 修改失败
// @router /UpdateUserinfo/ [put]
func (u *UserController) UpdateUserinfo() {
	var userinfo models.User
	err2 := json.Unmarshal(u.Ctx.Input.RequestBody, &userinfo)
	if err2 != nil {
		u.Data["json"] = models.GetRevaErr(err2, "获取json结构体失败")
		u.ServeJSON()
		return
	}
	_, err := u.o.Update(&userinfo)
	if err != nil {
		u.Data["json"] = models.GetRevaErr(err, "后台操作数据库失败")
		u.ServeJSON()
		return
	}
	u.Data["json"] = models.GetRevaOk(userinfo)
	u.ServeJSON()
}
